package com.tsysytems.gui;

import java.awt.Component;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumnModel;

import com.tsystems.entities.TimeTableElement;

public class BuyTicketTableElementTable extends JTable {

	private static final long serialVersionUID = 161550993195410518L;
	private TicketTableElementsTableModel model;
	private ListSelectionListener listener;

	public BuyTicketTableElementTable() {
		model = new TicketTableElementsTableModel();

		setModel(model);

		setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {

			private static final long serialVersionUID = -4448416295222440127L;

			@Override
			public Component getTableCellRendererComponent(JTable table,
					Object value, boolean isSelected, boolean hasFocus,
					int row, int column) {
				super.getTableCellRendererComponent(table, value, isSelected,
						hasFocus, row, column);

				if (value != null) {
					this.setText(TicketTableElementsColumns.values()[column]
							.format(value));
				}
				return this;
			}
		});

		TableColumnModel columnModel = getColumnModel();

		for (int i = 0; i < TicketTableElementsColumns.values().length; i++) {
			int width = TicketTableElementsColumns.values()[i].getWidth();
			columnModel.getColumn(i).setPreferredWidth(width);
		}

		getTableHeader().setReorderingAllowed(false);
		getSelectionModel().setSelectionMode(
				ListSelectionModel.SINGLE_SELECTION);

		getSelectionModel().addListSelectionListener(
				new ListSelectionListener() {
					public void valueChanged(ListSelectionEvent e) {
						listener.valueChanged(e);
					}
				});
	}

	public TimeTableElement getSelectedTimeTableElement() {
		int selectRow = getSelectedRow();
		return selectRow >= 0 ? model.getData(selectRow) : null;
	}

	public List<TimeTableElement> getTimeTableElements() {
		return model.getCheckedMessages();
	}

	public TicketTableElementsTableModel getModel() {
		return model;
	}

	public void setSelectListener(ListSelectionListener listener) {
		this.listener = listener;
	}

	public void updateTable(List<TimeTableElement> stations) {
		model.setData(stations);
	}
}

class TicketTableElementsTableModel extends AbstractTableModel {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3213358527382430135L;
	private List<TimeTableElement> data;
	private boolean[] select;

	public TicketTableElementsTableModel() {
		data = new ArrayList<TimeTableElement>();
		select = new boolean[0];
	}

	public void setData(List<TimeTableElement> data) {
		this.data = data;
		select = new boolean[data.size()];
		fireTableDataChanged();
	}

	public TimeTableElement getData(int row) {
		return data.get(row);
	}

	public int getRowCount() {
		return data.size();
	}

	@Override
	public String getColumnName(int column) {
		return TicketTableElementsColumns.values()[column].getTitle();
	}

	public int getColumnCount() {
		return TicketTableElementsColumns.values().length;
	}

	public Object getValueAt(int rowIndex, int columnIndex) {
		TicketTableElementsColumns column = TicketTableElementsColumns.values()[columnIndex];
		return column.getValue(data.get(rowIndex));
	}

	@Override
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		if (columnIndex == 0) {
			select[rowIndex] = (Boolean) aValue;
		}
	}

	@Override
	public Class<?> getColumnClass(int columnIndex) {
		return TicketTableElementsColumns.values()[columnIndex].getColumnClass();
	}

	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return TicketTableElementsColumns.values()[columnIndex].isCellEditable();
	}

	public List<TimeTableElement> getCheckedMessages() {
		List<TimeTableElement> result = new ArrayList<TimeTableElement>();

		for (int i = 0; i < select.length; i++) {
			if (select[i]) {
				result.add(data.get(i));
			}
		}

		return result;
	}

}

enum TicketTableElementsColumns {

	DEPARTMENT_STATION("Станция отправления", 300) {
		@Override
		public Object getValue(TimeTableElement m) {
			return m.getDepartureStation().getName();
		}
	},
	

	DEPARTMENT_TIME("Время отправления", 300) {
		@Override
		public Object getValue(TimeTableElement m) {
			return m.getDepartureTime();
		}
		public String format(Object obj) {
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
					"HH:mm  dd:MM:yyyy");
			return simpleDateFormat.format((Date) obj);
		}
	},

	ARRIVAL_STATION("Станция прибытия", 300) {
		@Override
		public Object getValue(TimeTableElement m) {
			return m.getArrivalStation().getName();
		}
	},

	ARRIVAL_TIME("Время прибытия", 300) {
		@Override
		public Object getValue(TimeTableElement m) {
			return m.getArrivalTime();
		}
		public String format(Object obj) {
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
					"HH:mm  dd:MM:yyyy");
			return simpleDateFormat.format((Date) obj);
		}
	};

	private final String title;
	private final int width;

	TicketTableElementsColumns(String title, int width) {
		this.title = title;
		this.width = width;
	}

	public String getTitle() {
		return title;
	}

	public int getWidth() {
		return width;
	}

	public String columnName() {
		return title;
	}

	public String format(Object arg0) {
		return arg0 == null ? "" : arg0.toString();
	}

	public Class<?> getColumnClass() {
		return String.class;
	}

	public boolean isCellEditable() {
		return false;
	}

	public abstract Object getValue(TimeTableElement m);
}
